﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Simpletron
{
  public class Memory : IMemoryDump
  {
    public static readonly int maxMemoryLocation = int.MaxValue / 10000000;
    public static readonly int minMemoryLocation = 0;

    private int[] memory;

    /// <summary>
    /// Gets the size of the memory object.
    /// </summary>
    public int Size { get { return (int)memory.Length; } }

    private Memory(int size)
    {
      if (size >= (int.MaxValue % 10000000))
      {        
        throw new ApplicationException(string.Format("Memory size can not exceed {0}", int.MaxValue % 100000000));
      }

      memory = new int[size];
    }

    private void Initialize()
    {
      Initialize(0);
    }

    private void Initialize(byte value)
    {
      for (int i = 0; i < memory.Length; i++) { memory[i] = 0; }
    }

    /// <summary>
    /// Gets or sets a value on a given memory location.
    /// </summary>
    /// <param name="index">An index pointing at a memory location.</param>
    /// <returns>Returns an integer from a given memory location.</returns>
    public int this[int index]
    {
      get { return memory[index]; }
      set { memory[index] = value; }
    }

    /// <summary>
    /// Creates a memory object with a default size of 30000 and initilized to 0.
    /// </summary>
    /// <returns>Returns a memory object.</returns>
    public static Memory DefaultMemory()
    {
      return CustomMemory(30000, 0);
    }

    /// <summary>
    /// Creates a memory object.
    /// </summary>
    /// <param name="Size">Size of the memory.</param>
    /// <param name="initialValue">Memory initalization value.</param>
    /// <returns></returns>
    public static Memory CustomMemory(int Size, byte initialValue)
    {
      Memory mem = new Memory(Size);
      mem.Initialize(initialValue);

      return mem;
    }

    public void Dump(IMemoryDumpWriter writer)
    {
      writer.WriteDump("\nMemory");
      writer.WriteDump("Address\t\tvalue\tAscii");      
    }

    #region ICloneable Members

    public object Clone()
    {
      throw new NotImplementedException();
    }

    #endregion
  }
}
